<template>
    <div>

        <div v-for="data in dataList" :key="data.id" >
            <div style="margin: 15px 0;"></div>
            <el-checkbox :indeterminate="checkIndeterminate.indexOf(data.id) !== -1" v-model="checkAll" :label="data.id"
                         @change="handleCheckAllChange(...arguments, data)">{{data.name}}
            </el-checkbox>
            <el-checkbox-group v-model="checkedData" @change="handleCheckedCitiesChange(data)">
                <el-checkbox v-for="child in data.children" :label="child.id" :key="child.id">{{child.name}}
                </el-checkbox>
            </el-checkbox-group>
        </div>

    </div>
</template>

<script>
    /**
     * 树状 - 多选框水平展示组件
     */
    export default {
        name: "index",
        data() {
            return {
                //父节点选择
                checkAll: [],
                //叶子选择
                checkedData: [],
                checkIndeterminate: [],
            }
        },
        props: {
            dataList: {
                type: Array,
                default() {
                    return [];
                }
            }
        },
        methods: {
            /**
             * 全选 -- 影响子节点数据
             * 默认两个参数 通过...arguments 获取，后续在即添加自定参数
             */
            handleCheckAllChange(checked, event, data) {
                //当前节点对应叶子结点数据组
                let checkNodeArr = data ?
                        (this.dataList.filter(item => item.id === data.id))[0].children.map(item=>item.id) : [];

                checked? this.checkedData.push(...checkNodeArr)
                        :this.checkedData=this.checkedData.filter(dateItem=>checkNodeArr.indexOf(dateItem) === -1);

                //触发全选时，部分选 清理掉
                this.checkIndeterminate=this.checkIndeterminate.filter(itemData=>itemData !== data.id);
                this.$emit("change",this.checkedData);
            },

            /**
             * 单选属性 - 影响父节点数据 -通过数据对比 确定父节点状态
             * @param data 当前父节点数据
             */
            handleCheckedCitiesChange(data) {

                //当前节点对应叶子结点数据组
                let checkNodeArr = data ?
                        (this.dataList.filter(item => item.id === data.id))[0].children.map(item=>item.id) : [];
                let nowNodeArr = [];// 父节当前数据组 1、没有 2、部分 3、全部
                this.checkedData.forEach(dataItem=>{
                    if(checkNodeArr.indexOf(dataItem) !== -1){
                        nowNodeArr.push(dataItem);
                    }
                });

                //判定数据选中量
                let checkedCount = nowNodeArr.length;
                if(checkedCount === checkNodeArr.length){
                    //未全选 - 清理全选标记
                    if(this.checkAll.indexOf(data.id) === -1) {
                        this.checkAll.push(data.id);
                    }
                    this.checkIndeterminate=this.checkIndeterminate.filter(itemData=>itemData !== data.id)
                }
                if(checkedCount > 0 && checkedCount < checkNodeArr.length) {
                    //未全选 - 清理全选标记
                    this.checkAll=this.checkAll.filter(itemData=>itemData !== data.id)
                    //添加部分选择的标记
                    if(this.checkIndeterminate.indexOf(data.id) === -1) {
                        this.checkIndeterminate.push(data.id);
                    }
                }
                if(checkedCount === 0){
                    this.checkAll=this.checkAll.filter(itemData=>itemData !== data.id)
                    this.checkIndeterminate=this.checkIndeterminate.filter(itemData=>itemData !== data.id)
                }
                this.$emit("change",this.checkedData);
            }
        }
    }
</script>

<style scoped>

</style>